﻿// <copyright file="Transform3D.cs" company="Axelerate Solutions S.A.">
// Copyright (c) Axelerate Solutions S.A.  All rights reserved.
// </copyright>

namespace Axelerate.Silverlight3D.Media.Media3D
{
    using System;
    using System.Net;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Ink;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Shapes;

    /// <summary>
    /// File name: Transform3D.cs
    /// Company: Axelerate Solutions S.A.
    /// Created By: Daniel Rojas
    /// Created Date: 10/07/2008 15:11:00 h.
    /// Description: Provides a parent class for all three-dimensional transformations, including translation, rotation, and scale transformations.
    ///   <Modifications>
    ///   </Modifications>
    /// </summary>
    /// <remarks>
    /// Use the MatrixTransform3D class to create transformations not available from the RotateTransform3D, TranslateTransform3D, and ScaleTransform3D classes.
    /// </remarks>
    public abstract class Transform3D : GeneralTransform3D
    {
        #region Properties
        /// <summary>
        /// Gets the identity transformation.
        /// </summary>
        public static Transform3D Identity
        {
            get
            {
                return new MatrixTransform3D();
            }
        }
                
        /// <summary>
        /// Gets the Matrix3D that represents the value of the current transformation.
        /// </summary>
        public abstract Matrix3D Value { get; }

        /// <summary>
        /// Gets a value that specifies whether the matrix is affine.
        /// </summary>
        public abstract bool IsAffine { get; }

        /// <summary>
        /// Transforms the specified 3-D point and returns the result.
        /// </summary>
        /// <param name="point">The 3-D point to transform.</param>
        /// <returns>The result of transforming point.</returns>
        public override GeneralTransform3D Inverse
        {
            get
            {
                Matrix3D m = Matrix3D.Identity;
                m = m * Value;
                m.Invert();
                return new MatrixTransform3D(m);
            }
        }
        #endregion

        #region Properties

        /// <summary>
        /// Transforms the specified array of Point3D objects.
        /// </summary>
        /// <param name="points">Array of Point3D objects to transform.</param>
        public void Transform(Point3D[] points)
        {
            Value.Transform(points);
        }

        /// <summary>
        /// Transforms the specified Vector3D.
        /// </summary>
        /// <param name="vector">Vector3D to transform.</param>
        /// <returns>Transformed Vector3D.</returns>
        public Vector3D Transform(Vector3D vector)
        {
            return Value.Transform(vector);
        }

        /// <summary>
        /// Transforms the specified array of Vector3D objects.
        /// </summary>
        /// <param name="vectors">Array of Vector3D objects to transform.</param>
        public void Transform(Vector3D[] vectors)
        {
            Value.Transform(vectors);
        }

        /// <summary>
        /// Transforms the specified 3-D bounding box and returns an axis-aligned 3-D bounding box that is exactly large enough to contain it.
        /// </summary>
        /// <param name="rect">The 3-D bounding box to transform.</param>
        /// <returns>The smallest axis-aligned 3-D bounding box possible that contains the transformed rect.</returns>
        public override Rect3D TransformBounds(Rect3D rect)
        {
            return Value.Transform(rect);
        }

        /// <summary>
        /// Attempts to transform the specified 3-D point and returns a value that indicates whether the transformation was successful.
        /// </summary>
        /// <param name="inPoint">The 3-D point to transform.</param>
        /// <param name="result">The 3-D point to transform.</param>
        /// <returns>true if inPoint was transformed; otherwise, false.</returns>
        /// <remarks>Unlike the Transform method, this method does not throw an exception if the transformation is unsuccessful.</remarks>
        public override bool TryTransform(Point3D inPoint, out Point3D result)
        {
            try
            {
                result = Value.Transform(inPoint);
                return true;
            }
            catch (Exception ex)
            {
                result = new Point3D();
                System.Diagnostics.Debug.WriteLine(ex.Message);
                return false;
            }
        }
        #endregion
    }
}
